package com.example.learningspringboot.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;


/**
 * 这是一个切面类，展示怎么使用 AspectJ 注解来定义切面。
 */
@Component
@Aspect
public class AuthAspect {

    /**
     * 定义一个切点，匹配 AspectService 类中的所有方法。
     * 这里的 bean(aspectService) 是指匹配名为 aspectService 的 Bean
     * 如果你有多个 Bean，可以使用 bean 包名 + 类名 的方式来匹配。
     * 具体的还是要网络上查找相关的 AspectJ 表达式。
     */
//    @Pointcut("bean(aspectService)")
    @Pointcut("execution(* com.example.learningspringboot.service.AspectService.*())")
    public void pointCut() {

    }

    /**
     * 在方法执行前进行一些处理，比如认证逻辑。
     * 切面前置处理
     */
    @Before("pointCut()")
    public void before(JoinPoint joinPoint) {
        System.out.println("Aspect Before : " + joinPoint.getSignature().getName());
    }

    /**
     * 在方法执行后进行一些处理，比如记录日志等。
     * 切面后置处理
     */
    @After("pointCut()")
    public void after(JoinPoint joinPoint) {
        System.out.println("Aspect After : " + joinPoint.getSignature().getName());
    }

    /**
     * 在方法执行后返回结果时进行一些处理，比如记录日志等。
     * 切面后返回处理，这个是执行没有问题切面
     * @param joinPoint 切点信息
     */
    @AfterReturning("pointCut()")
    public void afterReturning(JoinPoint joinPoint) {
        System.out.println("Aspect After Returning: " + joinPoint.getSignature().getName());
    }

    /**
     * 在方法执行后返回结果时进行一些处理，比如记录日志等。
     * 切面后返回处理，这个是执行报错的切面
     * @param joinPoint 切点信息
     */
    @AfterThrowing("pointCut()")
    public void afterThrowing(JoinPoint joinPoint) {
        System.out.println("Aspect After Throwing: " + joinPoint.getSignature().getName());
    }

    /**
     * 环绕通知，允许在方法执行前后进行处理。
     * @param joinPoint 切点信息
     * @return 返回目标方法的执行结果
     * @throws Throwable 可能抛出的异常
     */
    @Around("pointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("Aspect Around Before: " + joinPoint.getSignature().getName());
        Object result = joinPoint.proceed(); // 执行目标方法
        System.out.println("Aspect Around After: " + joinPoint.getSignature().getName());
        return result;
    }

}
